package com.ruoyi.zsix.service.manager;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.RedisUtils;
import com.ruoyi.zsix.domain.model.ProcessDefinitionParams;
import com.ruoyi.zsix.domain.model.TaskDefinition;
import com.ruoyi.zsix.domain.model.TaskModel;
import com.ruoyi.zsix.domain.process.FlowEntity;
import com.ruoyi.zsix.domain.taskAssignee.FlowElementAttrs;
import com.ruoyi.zsix.domain.taskAssignee.OvProcessInstance;
import com.ruoyi.zsix.strategy.manager.SequenceFlowManager;
import lombok.RequiredArgsConstructor;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.RepositoryService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.UUID;

@Component
@RequiredArgsConstructor
public class IProcessDefinitionManager {
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private MapperManager mapperManager;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private SequenceFlowManager sequenceFlowManager;
    @Autowired
    private IProcessDefManager iProcessDefManager;
    private Long expireTime=Long.parseLong("360000") ;

    /**
     * 流程信息保存到redis
     * @return
     */
    public OvProcessInstance saveOvProcessInstance(String process_key, ProcessDefinitionParams params){
        if(redisUtils.exists(process_key)){
            redisUtils.remove(process_key);
        }
        redisUtils.set(process_key,JSON.toJSONString(params),expireTime);
        return null;
    }
    /**
     * 创建一个流程属性
     * @param process_key
     * @return
     */
    public ProcessDefinitionParams getParams(String process_key){
        ProcessDefinitionParams params=new ProcessDefinitionParams();
        //判断redis中是否存在
        if(redisUtils.exists(process_key)){
            params= com.alibaba.fastjson.JSONObject.parseObject(redisUtils.get(process_key).toString(),ProcessDefinitionParams.class);
        }
        else {
            params.setKey(process_key);
            //标题生成规则
            params.setTitleModel("");
            //流程业务分类
            params.setSortid("");
        }
        return params;
    }

    /**
     * 流程信息保存到redis
     * @return
     */
    public FlowElementAttrs saveFlowElementAttrs(String task_def_key, TaskDefinition taskDefinitionParams){
        if(redisUtils.exists("UserTask_"+task_def_key)){
            redisUtils.remove("UserTask_"+task_def_key);
        }
        redisUtils.set("UserTask_"+task_def_key, JSON.toJSONString(taskDefinitionParams),expireTime);
        return null;
    }
    /**
     * 创建节点
     * @param deploymentId
     */
    public void createTask(String deploymentId){
        OvProcessInstance ovProcessInstance=mapperManager.getProcessInsByDeployId(deploymentId);
        BpmnModel bpmnModel = repositoryService.getBpmnModel(ovProcessInstance.getId_());
        //获取流程信息
        Process process=bpmnModel.getProcesses().get(0);
        Collection<FlowElement> flowElements=process.getFlowElements();
        List<TaskDefinition> userTasks=new ArrayList<>();
        for(FlowElement flowElement : flowElements){
            if (flowElement instanceof UserTask){
                //节点信息
                UserTask userTask=(UserTask) flowElement;
                String usertaskId=userTask.getId();
                //获取处理人规则
                String candidateUsers=userTask.getCandidateUsers().get(0);
                String ruleName=sequenceFlowManager.getRuleName(userTask.getId(),candidateUsers);

                //创建时，如果没有设置接收人，发布时报错,先将错误屏蔽
                try {
                    String assigneeString = "";
                    //读取缓存中设置的处理人数据
                    if (redisUtils.exists(usertaskId + "_" + ruleName)) {
                        assigneeString = redisUtils.get(usertaskId + "_" + ruleName).toString();
                        iProcessDefManager.deleteAssigneeUserByTaskid(usertaskId);
                        iProcessDefManager.setAssigneeUser(assigneeString, usertaskId, ruleName);
                    }
                }
                catch (Exception ex){

                }
                Boolean isExists=true;
                FlowElementAttrs flowElementAttrs= mapperManager.getFlowElementAttrs(usertaskId);
                if(flowElementAttrs==null){
                    flowElementAttrs=createFlowElementAttrs();
                    flowElementAttrs.setId(UUID.randomUUID().toString());
                    flowElementAttrs.setTask_def_key(usertaskId);
                    flowElementAttrs.setProcess_key(ovProcessInstance.getKey_());
                    isExists=false;
                }
                if(!isExists){
                    mapperManager.setFlowElementAttrs(flowElementAttrs);
                }
                TaskDefinition taskDefinitionParams=getTaskDefinitionParams(usertaskId);
                userTasks.add(taskDefinitionParams);
            }
        }
        deployWithParams(ovProcessInstance.getKey_(),userTasks);
    }
    /**
     * 根据参数发布流程
     * @param process_key
     * @param userTasks
     */
    public void deployWithParams(String process_key,List<TaskDefinition> userTasks){
        ProcessDefinitionParams params=getParams(process_key);
        params.setUserTasks(userTasks);
        updateDeployment(params);
    }
    /**
     * 配置更新
     * @param params
     * @return
     */
    public String updateDeployment(ProcessDefinitionParams params){
        updateProcessProperties(params);
        //设置节点信息
        List<TaskDefinition> taskDefinitionParams=params.getUserTasks();
        for(TaskDefinition taskParams:taskDefinitionParams){
            //节点功能设置
            TaskModel taskModel=taskParams.getFormModel();
            FlowElementAttrs taskElementAttrs=new FlowElementAttrs();
            BeanUtils.copyProperties(taskModel,taskElementAttrs);
            taskElementAttrs.setTask_def_key(taskParams.getId());
            taskElementAttrs.setProcess_key(params.getKey());
            taskElementAttrs.setRefuse(taskModel.getRefuse());
            taskElementAttrs.setEndTask(taskModel.getEndTask());
            taskElementAttrs.setCountersign(taskModel.getCountersign());
            taskElementAttrs.setTransfer(taskModel.getTransfer());
            mapperManager.updateFlowElementAttrs(taskElementAttrs);
        }

        return "执行成功";
    }
    /**
     * 更新流程属性
     * @param params
     */
    public void updateProcessProperties(ProcessDefinitionParams params){
        saveOvProcessInstance(params.getKey(),params);
        //更新流程部署信息，将引擎版本号作为流程类别
        FlowEntity flowEntity=new FlowEntity();
        flowEntity.setId_(params.getId());
        flowEntity.setName_(params.getName());
        flowEntity.setProcessKey(params.getKey());
        flowEntity.setEngine_version_(params.getSortid());
        flowEntity.setName_(params.getName());
        mapperManager.updateFlowEntity(flowEntity);

        //更新标题生成规则
        FlowElementAttrs flowElementAttrs=new FlowElementAttrs();
        flowElementAttrs.setProcess_key(params.getKey());
        flowElementAttrs.setTitleModel(params.getTitleModel());
        mapperManager.updateTitleModel(flowElementAttrs);

    }
    /**
     * 创建一个空的节点属性
     * @return
     */
    public FlowElementAttrs createFlowElementAttrs(){
        FlowElementAttrs flowElementAttrs=new FlowElementAttrs();
        flowElementAttrs.setRunWay("none");
        flowElementAttrs.setReturnWay("none");
        flowElementAttrs.setTransfer(0);
        flowElementAttrs.setCountersign(0);
        flowElementAttrs.setJumpWay("none");
        flowElementAttrs.setEndTask(0);
        flowElementAttrs.setRefuse(0);
        flowElementAttrs.setCcWay("none");
        flowElementAttrs.setAutoCCWay("none");
        return flowElementAttrs;
    }
    /**
     * 创建一个空的节点属性
     * @param task_def_key
     * @return
     */
    public TaskDefinition getTaskDefinitionParams(String task_def_key){
        TaskDefinition taskDefinitionParams=new TaskDefinition();
        //判断redis中是否存在
        if(redisUtils.exists("UserTask_"+task_def_key)){
            taskDefinitionParams= JSONObject.parseObject(redisUtils.get("UserTask_"+task_def_key).toString()
                    ,TaskDefinition.class);
        }
        else {
            //创建一个空的基本信息
            FlowElementAttrs taskElementAttrs=createFlowElementAttrs();
            TaskModel taskModel = new TaskModel();
            BeanUtils.copyProperties(taskElementAttrs, taskModel);
            //组织数据
            taskDefinitionParams.setFormModel(taskModel);
        }
        return taskDefinitionParams;
    }
}
